package main.model.critters;


import java.util.logging.Level;
import java.util.logging.Logger;

import main.model.hexisland.HexIsland;
import main.model.hexisland.SubTileUtil;
import main.model.hexisland.location.HexLocation;
import main.model.hexisland.location.SubHexLocation;


public class LocationValidator {
	
	private static final Logger LOG = Logger.getLogger("LocationValidator");
	CritterCensus census;
	private HexIsland island;
	
	
	public LocationValidator(CritterCensus census){
        LOG.setLevel(Level.FINEST);

        this.census = census;
		this.island = census.getIsland();
	}

	public void checkAllCritters(){
        if(census != null
                && census.getCritters() != null){
            for(Critter c : census.getCritters()){
                if(!checkAccessibility(c,null)){
                    critterNewLocation(c);
                }
            }
        }
	}
	
	private boolean checkAccessibility (Critter c, SubHexLocation location){
		//LOG.fine("Checking critter "+c.toString());
        if(location == null) location = c.getLocation();

        if( !SubTileUtil.isAccessible(island , location, c.isLargeCritter())) return false;

        for(Critter a : census.getCritters()){
            if(a.isAlive()){
                if(a != c && a.getLocation().equals(location)){
                    return false;
                }
            }
        }
        return true;

	}
	
	private void critterNewLocation(Critter c){
        for(int i = 0; i < 6 ; i++){
            SubHexLocation testLocation = new SubHexLocation(c.getLocation(),i);
            if(checkAccessibility(c , testLocation)){
                //LOG.info("moving "+c.toString()+" from "+c.getLocation().toString()+" to "+testLocation);
                c.setLocation(testLocation);
                return;
            }
        }

		int r = 1;
		while(true){
            HexLocation H = SubTileUtil.findNeighbour(c.getLocation(), 0);

            for(int angle = 0; angle < 6 ; angle++){
                for(int step = 0; step < r; step++){
                    for(int sector = 0; sector < 6 ; sector++){
                        if(checkAccessibility(c, new SubHexLocation(H,sector))){
                            c.setLocation(new SubHexLocation(H,sector));
                            return;
                        }
                    }
                    H = SubTileUtil.findNeighbour(H , angle);
                }
            }
			r++;
			if(r > island.getQSize() && r >island.getRSize()){
				LOG.info("No spaces found, Killing critter "+c.toString());
				c.kill();
				return;
			}
		}
	}
}
